﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.DataTransformationServices.Controls;
using Microsoft.SqlServer.Dts.Runtime;

namespace SSISFileWatcherTask100
{
    public partial class frmEditProperties : Form
    {
        #region Private Properties
        private readonly TaskHost _taskHost;
        private readonly Connections _connections;
        private readonly Variables _variables;
        #endregion

        #region Public Properties
        private Variables Variables
        {
            get { return _taskHost.Variables; }
        }

        private Connections Connections
        {
            get { return _connections; }
        }

        #endregion

        #region .ctor
        public frmEditProperties(TaskHost taskHost, Connections connections)
        {
            InitializeComponent();

            _taskHost = taskHost;
            _connections = connections;

            if (taskHost == null)
            {
                throw new ArgumentNullException("taskHost");
            }

            _variables = taskHost.Variables;

            try
            {
                InitializeForm();
                if (_taskHost.Properties[Keys.InputType].GetValue(_taskHost) != null)
                {
                    optConnectionFile.Checked = _taskHost.Properties[Keys.InputType].GetValue(_taskHost).ToString() == Keys.TRUE;
                    optVariable.Checked = _taskHost.Properties[Keys.InputType].GetValue(_taskHost).ToString() == Keys.FALSE;
                }
                else
                    optConnectionFile.Checked = true;

                chkIncludeSubdirectories.Checked = _taskHost.Properties[Keys.IncludeSubdirectories].GetValue(_taskHost) != null && _taskHost.Properties[Keys.IncludeSubdirectories].GetValue(_taskHost).ToString() == Keys.TRUE;

                if (_taskHost.Properties[Keys.InputFolderPath].GetValue(_taskHost) != null)
                    cmbPath.SelectedIndex = GetSelectedComboBoxIndex(cmbPath, _taskHost.Properties[Keys.InputFolderPath].GetValue(_taskHost));

                if (_taskHost.Properties[Keys.FileFilter].GetValue(_taskHost) != null)
                    cmbFilePattern.SelectedIndex = GetSelectedComboBoxIndex(cmbFilePattern, _taskHost.Properties[Keys.FileFilter].GetValue(_taskHost));

                if (_taskHost.Properties[Keys.Timeout].GetValue(_taskHost) != null)
                    cmbTimeout.SelectedIndex = GetSelectedComboBoxIndex(cmbTimeout, _taskHost.Properties[Keys.Timeout].GetValue(_taskHost));

                if (_taskHost.Properties[Keys.OutputVariableName].GetValue(_taskHost) != null)
                    cmbOut.SelectedIndex = GetSelectedComboBoxIndex(cmbOut, _taskHost.Properties[Keys.OutputVariableName].GetValue(_taskHost));

                if (_taskHost.Properties[Keys.FireOn].GetValue(_taskHost) != null)
                {
                    var actions = _taskHost.Properties[Keys.FireOn].GetValue(_taskHost).ToString().Split(',');

                    foreach (ListViewItem lstItem in lstViewActions.Items)
                    {
                        foreach (var action in actions)
                        {
                            if (action == lstItem.Text)
                                lstItem.Checked = true;
                        }
                    }

                    //foreach (ListViewItem lstItem in from action in actions
                    //                                 from ListViewItem lstItem in lstViewActions.Items
                    //                                 where action == lstItem.Text
                    //                                 select lstItem)
                    //{
                    //    lstItem.Checked = true;
                    //}
                }
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message);
            }
        }

        private void InitializeForm()
        {
            lstViewActions.Items.Clear();
            cmbFilePattern.Items.Clear();
            cmbTimeout.Items.Clear();
            cmbOut.Items.Clear();

            foreach (var varDyct in Keys.Actions)
                lstViewActions.Items.Add(varDyct.Key, varDyct.Value);

            LoadFileConnections();

            cmbTimeout.Items.Add("0");
            cmbFilePattern.Items.Add("*.*");

            cmbTimeout.Items.AddRange(LoadUserVariables("System.Int32").ToArray());
            cmbTimeout.Items.AddRange(LoadUserVariables("System.Int16").ToArray());
            cmbFilePattern.Items.AddRange(LoadUserVariables("System.String").ToArray());
            cmbOut.Items.AddRange(LoadUserVariables("System.String").ToArray());

            cmbTimeout.SelectedIndex = 0;
            cmbFilePattern.SelectedIndex = 0;
        }

        #endregion

        #region Methods

        private static int GetSelectedComboBoxIndex(ComboBox comboBox, object value)
        {
            int retValue = -1;

            if (value == null)
                return retValue;

            if (string.IsNullOrEmpty(value.ToString()))
                return retValue;

            string strValue = value.ToString();

            if (comboBox.FindString(strValue) > -1)
            {
                retValue = comboBox.FindString(strValue);
            }
            else
            {
                comboBox.Items.Add(strValue);
                retValue = comboBox.FindString(strValue);
            }

            return retValue;
        }

        private void LoadFileConnections()
        {
            cmbPath.Items.Clear();

            foreach (var connection in Connections.Cast<ConnectionManager>().Where(connection => connection.CreationName == "FILE"))
            {
                cmbPath.Items.Add(connection.Name);
            }
        }

        private List<string> LoadUserVariables(string parameterInfo)
        {
            return (from Variable var in _variables
                    where var.DataType == Type.GetTypeCode(Type.GetType(parameterInfo)) && var.Namespace.ToLower() == "user"
                    select string.Format("@[{0}::{1}]", var.Namespace, var.Name)).ToList();
        }

        #endregion

        #region Events

        private void btSave_Click(object sender, EventArgs e)
        {
            _taskHost.Properties[Keys.InputFolderPath].SetValue(_taskHost, cmbPath.Text);
            _taskHost.Properties[Keys.InputType].SetValue(_taskHost, optConnectionFile.Checked ? Keys.TRUE : Keys.FALSE);
            _taskHost.Properties[Keys.FileFilter].SetValue(_taskHost, cmbFilePattern.Text);

            _taskHost.Properties[Keys.IncludeSubdirectories].SetValue(_taskHost, chkIncludeSubdirectories.Checked ? Keys.TRUE : Keys.FALSE);
            _taskHost.Properties[Keys.Timeout].SetValue(_taskHost, cmbTimeout.Text);
            _taskHost.Properties[Keys.OutputVariableName].SetValue(_taskHost, cmbOut.Text);

            var fireOn = new StringBuilder();

            foreach (ListViewItem lstItem in lstViewActions.Items.Cast<ListViewItem>().Where(lstItem => lstItem.Checked))
            {
                fireOn.Append(string.Format("{0},", lstItem.Text));
            }

            _taskHost.Properties[Keys.FireOn].SetValue(_taskHost, fireOn.ToString());

            DialogResult = DialogResult.OK;
            Close();
        }

        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            System.Diagnostics.Process.Start(linkLabel1.Text);
        }

        private void btExpressionPath_Click(object sender, EventArgs e)
        {
            using (ExpressionBuilder expressionBuilder = ExpressionBuilder.Instantiate(_taskHost.Variables, _taskHost.VariableDispenser, typeof(string), cmbPath.Text))
            {
                if (expressionBuilder.ShowDialog() == DialogResult.OK)
                {
                    cmbPath.Text = expressionBuilder.Expression;
                }
            }
        }

        private void optConnectionFile_CheckedChanged(object sender, EventArgs e)
        {
            btExpressionPath.Enabled = optVariable.Checked;
            cmbPath.Items.Clear();
            LoadFileConnections();
        }

        private void optVariable_CheckedChanged(object sender, EventArgs e)
        {
            btExpressionPath.Enabled = optVariable.Checked;
            cmbPath.Items.Clear();
            cmbPath.Items.AddRange(LoadUserVariables("System.String").ToArray());
        }

        #endregion
    }
}
